var Tx = require('ethereumjs-tx');
var future = require("./futuer");
var ABI = require('./abi');

class Transfer {

    constructor(web3) {
        this._web3 = web3;
    }

    /**
     * 代币转账
     * @param contractAddress 合约地址
     * @param from 发送人地址
     * @param to 接收人地址
     * @param 私钥
     * @param gasLimit
     * @param gasPrice
     * @return
     * @Author: laiyutao
     * @Date: 2021-08-03 14:28
     */
    async sendErc20Token(contractAddress, from, to, amount, privateKey, gasLimit, gasPrice) {
        // 合约对象
        let contract = new this._web3.eth.Contract(ABI, contractAddress);

        // 获取合约精度
        let error, decimals, balance, symbol;
        //[error, decimals] = await future(contract.methods.decimals().call());

        [error, balance] = await future(contract.methods.balanceOf(from).call());
        [error, symbol] = await future(contract.methods.symbol().call());

        console.log("账号余额：%s%s, 转账金额：%s%s", this._web3.utils.fromWei(balance), symbol, amount, symbol);

        // 查询指定地址发送的交易数量
        let count;
        [error, count] = await future(this._web3.eth.getTransactionCount(from));
        if (error != null) {
            console.log('获取交易数量失败：, ', error);
            throw error;
        }

        if (gasPrice == null) {
            [error, gasPrice] = await future(this._web3.eth.getGasPrice());
            if (error != null) {
                console.log('获取gas价格失败, %s', error.message);
                throw error;
            }
        } else {
            gasPrice = this._web3.utils.toWei(gasPrice, 'Gwei');
        }

        console.log("当前gas费：", this._web3.utils.fromWei(gasPrice, 'Gwei'));

        if (gasLimit == null) {
            gasLimit = 70000;
        }

        amount = this._web3.utils.toBN(amount);


        // 构建事务
        let txJson = {
            from: from,
            to: contractAddress,
            gasLimit: this._web3.utils.toHex(gasLimit),
            nonce: this._web3.utils.toHex(count),
            gasPrice: this._web3.utils.toHex(gasPrice),
            data: contract.methods.transfer(to, this._web3.utils.toWei(amount)).encodeABI()
        };


        if (privateKey.indexOf('0x') >= 0) {
            privateKey = privateKey.substring(2);
        }

        var tx = new Tx(txJson);
        var privateKeyBuff = Buffer.from(privateKey, 'hex');
        tx.sign(privateKeyBuff);

        var serializedTx = tx.serialize();

        // 发起转账
        let receipt;
        [error, receipt] = await future(this._web3.eth.sendSignedTransaction('0x' + serializedTx.toString('hex')));

        if (error != null) {
            console.log("转账失败：", error.message);
            throw error;
        }
        console.log('事务hash：', receipt.transactionHash);
        return receipt.transactionHash;
    }

}
module.exports = Transfer;